package com.ruoyi.framework.security.filter;


import com.ruoyi.common.utils.CommonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.AbstractRequestLoggingFilter;

import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.util.UUID;

/**
 * 打印请求地址、请求参数、响应时间等信息
 */
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
@WebFilter(filterName = "traceLogFilter", urlPatterns = "/*")
public class TraceUrlLogFilter extends AbstractRequestLoggingFilter {
    private static Logger log = LoggerFactory.getLogger(TraceUrlLogFilter.class);
    private final String TRACE_ID = "requestId"; // 线程追踪ID
    private final String BEGIN_TIME_MILLIS = "BEGIN_TIME_MILLIS";// 开始时间

    @Override
    protected void beforeRequest(HttpServletRequest request, String message) {

        MDC.put(BEGIN_TIME_MILLIS, String.valueOf(System.currentTimeMillis()));
        if (MDC.get(TRACE_ID) == null) {
            String traceId = UUID.randomUUID().toString().replaceAll("-", "");
            MDC.put(TRACE_ID, traceId);
        }
        log.info(CommonUtil.append("message:", message, " traceId: ", MDC.get(TRACE_ID)));
    }

    @Override
    protected void afterRequest(HttpServletRequest request, String message) {
        // 超过1秒的请求则认为是慢API请求
        if (System.currentTimeMillis() - Long.parseLong(MDC.get(BEGIN_TIME_MILLIS)) > 1000) {
            log.error(CommonUtil.append("slow api found!! afterRequest message:", message,
                    " takeTimeMillis: ", (System.currentTimeMillis() - Long.parseLong(MDC.get(BEGIN_TIME_MILLIS))),
                    "ms."
            ));
            return;
        }

        // LOGGER.info("接口信息{} 耗费时间{}ms", message, (System.currentTimeMillis() - Long.parseLong(MDC.get(BEGIN_TIME_MILLIS))));
        log.info(CommonUtil.append("afterRequest message:", message,
                " takeTimeMillis: ", (System.currentTimeMillis() - Long.parseLong(MDC.get(BEGIN_TIME_MILLIS))),
                "ms."
        ));
    }

    @Override
    public void destroy() {
        MDC.remove(TRACE_ID);
    }

    @Override
    protected boolean isIncludePayload() {
        return true;
    }

    @Override
    protected boolean isIncludeQueryString() {
        return true;
    }
}
